<?php
/**
* File holding the context class
*
* @author       Fabrice Douteaud <clearbudget@douteaud.com>
* @package      framework
* @access       public
*/

/***********************************************************************

  Copyright (C) 2008  Fabrice douteaud (clearbudget@douteaud.com)

    This file is part of ClearBudget.

    ClearBudget is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ClearBudget is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ClearBudget.  If not, see <http://www.gnu.org/licenses/>.


************************************************************************/

/**
* Class handling the context of each request. It maintains the context of the request by
* keeping all related variables to their original values and by letting other classes and files
* accessing them
* 
* @author       Fabrice Douteaud <clearbudget@douteaud.com>
* @package      framework
* @access       public
*/
class class_context {
  /**
	* @var array array of all variables coming from the user request (GET or POST)
	* @access private	
	*/
  private $vars = null;
	/**
	* @var object Hold the instance of the current class
	* @access private
	* @static	
	*/
  private static $_instance = null;
  
  /**
  * redirect to a different action 
	*	
	* @return void
	* @access public
	*/
  public function redirect($action) {
    $this->vars['action'] = $action;
    $this->vars['snippet'] = $action;
    }
  
  /**
	* magic method to access the private $vars variable 
	*	
	* This adds a layer between the user input and what the application is working with
	*     		
	* @return mixed the value if it exists or null
	* @access public
	*/
  public function __get($field) {
    if(isset($this->vars[$field])) {
      $return = $this->vars[$field];
      return $return;
      }
    return null;
    }

  /**
	* Save the action as the back action as it would come from the browser 
	*	
	* @param string the action to set     		
	* @return void
	* @access public	
	*/
  public function setBackAction($action) {
    $this->vars['backAction'] = $action;
    }

  
  /**
	* Gets the default language from the user-agent 
	*	
	* Reads the HTTP headers from the request for the HTTP_ACCEPT_LANGUAGE tag.
	* If found, it return the first language.
	*     		
	* @return mixed the language as a string is any OR boolean false
	* @access private	
	*/
  private function getUserAgentLanguage() {
    // if the user agent did not send anything, return false
    if (!isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) return false;

    // get all languages
    $langs=explode(",",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
    
    // get the first language in the list
    $lang=strtolower(substr($langs[0],0,2));
    
    // TODO : loop through all and sort them looking at the q flag
    // top q flag should be the language taken
    /* 
    //start going through each one
    foreach ($langs as $value) {
      //select only the first two letters
      $lang=substr($value,0,2);
      }
    */
    // make sure that the user agent language is valid
    $langs = explode(',', AVAILABLELANGUAGE);
    if(!in_array($lang, $langs)) {
      class_debug::addMsg(__FILE__, '"'.$lang.'" user agent language is not valid, defaulted to '.DEFAULTLANGUAGE, DEBUGDEBUG);
      $lang = DEFAULTLANGUAGE;
      }
    else {
      class_debug::addMsg(__FILE__, 'user agent language is '.$lang, DEBUGDEBUG);
      }
    return $lang;
    }

  /**
	* Sets the max number of month to look transaction from 
	*	
	* The max number of month to look up data for is used to avoid loading all the transactions from the DB.
	* This value is kept in a cookie. If no cookie is present, then a default value is applied.	
	*     
	* @param string the limit month  		
	* @return void
	* @access public	
	*/
  public function setlimitMonth($range, $limitMonth) {
    $this->vars['limitMonth'] = $limitMonth;
    $this->vars['range'] = $range;
    class_settings::updateUserSettings(true);
    //setcookie("limitMonth", $limitMonth);
    //setcookie("range", $range);
    }
    
  /**
	* Do some clean up on the var from the user 
	*	
	* @param string the var from the browser	
	* @return string the var trimmed and cleanned up
	* @access private	
	*/
  private function cleanVar($var) {
    $var = trim($var);
    return $var;
    }
  
  /**
	* Gets all vars from the user request 
	*	
	* @return void
	* @access private	
	*/
  private function getVars() {
    // preset some default value
    $this->vars['action'] = 'home';
    $this->vars['ajax'] = false;
    $this->vars['nextAction'] = false;
    
    $varArray = &$_GET;
    if(strtoupper($_SERVER["REQUEST_METHOD"]) == 'POST' && !isset($_FILES["qiffile"])) {
      $varArray = &$_POST;
      class_debug::addMsg(__FILE__, 'Request is POST', DEBUGDEBUG);
      }
    else {
      class_debug::addMsg(__FILE__, 'Request is GET', DEBUGDEBUG);
      }
    
    // loop through the input array
    foreach($varArray as $field=>$value) {
      $field = $this->cleanVar($field);
      $value = $this->cleanVar($value);
      $this->vars[$field]=$value;
      class_debug::addMsg(__FILE__, $field.'='.$value, DEBUGDEBUG);
      } 

    // we can set extra parameter in the action parameter as _param=value
    $extra = explode('_', $this->vars['action']);
    if($extra[0] != $this->vars['action']) { // we found the _
      foreach($extra as $key) { // for each param
        $tmp = explode('=', $key); // explode with '='
        if($tmp[0] != $key) {
          $this->vars[$tmp[0]]=$tmp[1];
          class_debug::addMsg(__FILE__, $tmp[0].'='.$tmp[1], DEBUGDEBUG);
          }
        }
      // cleanup the action var now
      $this->vars['action'] = $extra[0];
      }
    
    // by default the snippet = the action
    $this->vars['snippet'] = $this->vars['action'];
  
    }
  
  /**
	* Add a value to the context 
	*	
	* @return boolean true if successful, false if the name already exist
	* @access private	
	*/
  public function addToContext($name, $value) {
    if(isset($this->vars[$name])) return false;
    $this->vars[$name] = $value;
    return true;
    }
    
   
  /**
	* Initialize the context object by loading all the different values 
	*	
	*	
	* @return void
	* @access private	
	*/
  private function init() {
    // get all the vars from the browser
    $this->getVars();
    
    // get the Language from the settings object
    $this->vars['userLanguage'] = class_settings::getLanguage();
    
    // get the Currency from the settings object
    $this->vars['userCurrency'] = class_settings::getCurrency();
    
    // if user did not select a prefered language, set the language to the prefered user agent language
    if($this->vars['userLanguage'] == null || $this->vars['userLanguage'] == '') {
      // set the context var
      $this->vars['userLanguage'] = $this->getUserAgentLanguage();
      // set the user preference
      //class_settings::setLanguage($this->language);
      }
    
    // get the date range
    $this->vars['limitMonth'] = class_settings::getLimitMonth();
    $this->vars['range'] = class_settings::getRange();
    
    class_debug::addMsg(__FILE__, 'Request context loaded', DEBUGINFO);
    }
  
  /**
	* Get the login status of the current user
	*	
	* Reads the login cookie in order to determine the user login status	
	*	
	* @return boolean a flag set to true or false depending on the login status
	* @access public	
	*/
  public function isUserLoggedIn() {
    // check the user cookie to see if it is valid
    return class_usercookie::isCookieValid();
    }

  /**
	* Provide an instance of the current class 
	*	
	* Implementation of the singleton pattern
	*   		
	* @return object An instance of this class
	* @access public
	* @static	
	*/  
  public static function getInstance() {
    if(is_null(self::$_instance)) {
      self::$_instance = new self();
      }
    return self::$_instance;
    } // getInstance()

  /**
	* class constructor 
	*	
	* access to this class is private as to implement the singleton pattern
	*   	
	* @return void
	* @access private	
	*/
  private function __construct() {    
    // initialize the object
    $this->init();
    } // __construct()
  }
?>